/**
 *  @(#)  IFAAAuthenticator  module    1.0  2017/03/24
 *
 *  Copyright  (c)  2017,  IFAA  and/or  its  affiliates.  All  rights  reserved.
 *
 *  Redistribution  and  use  in  source  and  binary  forms,  with  or  without
 *  modification,  are  permitted  provided  that  the  following  conditions  are  met:
 *
 *  -Redistribution  of  source  code  must  retain  the  above  copyright  notice,  this
 *    list  of  conditions  and  the  following  disclaimer.
 *
 *  -Redistribution  in  binary  form  must  reproduce  the  above  copyright  notice,
 *    this  list  of  conditions  and  the  following  disclaimer  in  the  documentation
 *    and/or  other  materials  provided  with  the  distribution.
 *
 *  Neither  the  name  of  IFAA  or  the  names  of  contributors  may
 *  be  used  to  endorse  or  promote  products  derived  from  this  software  without
 *  specific  prior  written  permission.
 *
 *  This  software  is  provided  "AS  IS,"  without  a  warranty  of  any  kind.  ALL
 *  EXPRESS  OR  IMPLIED  CONDITIONS,  REPRESENTATIONS  AND  WARRANTIES,  INCLUDING
 *  ANY  IMPLIED  WARRANTY  OF  MERCHANTABILITY,  FITNESS  FOR  A  PARTICULAR  PURPOSE
 *  OR  NON-INFRINGEMENT,  ARE  HEREBY  EXCLUDED.  IFAA,  ORG.
 *  AND  ITS  LICENSORS  SHALL  NOT  BE  LIABLE  FOR  ANY  DAMAGES  SUFFERED  BY  LICENSEE
 *  AS  A  RESULT  OF  USING,  MODIFYING  OR  DISTRIBUTING  THIS  SOFTWARE  OR  ITS
 *  DERIVATIVES.  IN  NO  EVENT  WILL  IFAA  OR  ITS  LICENSORS  BE  LIABLE  FOR  ANY  LOST
 *  REVENUE,  PROFIT  OR  DATA,  OR  FOR  DIRECT,  INDIRECT,  SPECIAL,  CONSEQUENTIAL,
 *  INCIDENTAL  OR  PUNITIVE  DAMAGES,  HOWEVER  CAUSED  AND  REGARDLESS  OF  THE  THEORY
 *  OF  LIABILITY,  ARISING  OUT  OF  THE  USE  OF  OR  INABILITY  TO  USE  THIS  SOFTWARE,
 *  EVEN  IF  IFAA  HAS  BEEN  ADVISED  OF  THE  POSSIBILITY  OF  SUCH  DAMAGES.
 *
 *  You  acknowledge  that  this  software  is  not  designed,  licensed  or  intended
 *  for  use  in  the  design,  construction,  operation  or  maintenance  of  any
 *  nuclear  facility.
 *
 */
package com.ifaa.sdk.adapter;

import android.content.Context;
import android.os.Build;
import android.os.Bundle;

import com.ifaa.sdk.authenticatorservice.fingerprint.manager.IFAAFingerprintManagerAdapter;
import com.ifaa.sdk.authenticatorservice.fingerprint.task.FingerpirntTaskManager;
import com.ifaa.sdk.auth.AbstractAuthenticator;
import com.ifaa.sdk.auth.AuthInfo;
import com.ifaa.sdk.auth.AuthenticatorCallback;
import com.ifaa.sdk.auth.AuthenticatorLOG;
import com.ifaa.sdk.auth.Constants;
import com.ifaa.sdk.auth.message.AuthenticatorMessage;
import com.ifaa.sdk.auth.message.AuthenticatorResponse;
import com.ifaa.sdk.util.CommonUtils;

/**
 * IFAA Authenticator
 * @author qiyi.wxc
 * @version 1.0
 */
public class FingerprintAuthenticatorAdapter extends AbstractAuthenticator {

    private final static int TYPE = Constants.TYPE_FINGERPRINT;

    private IFAAFingerprintManagerAdapter mFingerprintManagerAdapter;

    public FingerprintAuthenticatorAdapter(Context context) {
        super();
        AuthenticatorLOG.fpInfo("IFAAManager FingerprintAuthenticatorAdapter launching");
        mFingerprintManagerAdapter = IFAAFingerprintManagerAdapter.getInstance(context);
        this.context = context.getApplicationContext();
    }

    @Override
    public boolean isSupported() {
        super.isSupported();
        int result = AuthenticatorResponse.RESULT_SUCCESS;
        try {
            if (mFingerprintManagerAdapter == null
                    || !mFingerprintManagerAdapter.isHardwareDetected()) {
                result = AuthenticatorResponse.RESULT_NOT_SUPPORT;
            }
        } catch (Exception e) {
            result = AuthenticatorResponse.RESULT_NOT_SUPPORT;
        }
        return result == AuthenticatorResponse.RESULT_SUCCESS ? true : false;
    }

    @Override
    public synchronized void process(AuthenticatorMessage request,
                        final AuthenticatorCallback authenticatorCallback) {

        request.setAuthenticatorType(TYPE);

        final Bundle messages = new Bundle();
        messages.putInt(AuthenticatorMessage.KEY_OPERATIONT_TYPE, request.getType());
        messages.putString(AuthenticatorMessage.KEY_MESSAGE, request.getData());
        messages
            .putInt(AuthenticatorMessage.KEY_AUTHENTICATOR_TYPE, request.getAuthenticatorType());
        messages.putString(AuthenticatorMessage.KEY_EXTRA_PARAMS, request.getExtraParams());
        messages.putInt("KEY_VERSION", request.getVersion());

        FingerpirntTaskManager.getInstance().runAsyncMessage(context, messages, authenticatorCallback);
    }

    private String mCachedDeviceId = "";

    /**
     *
     * 
     * @see com.ifaa.sdk.auth.IAuthenticator#getDeviceId()
     */
    @Override
    public synchronized String getDeviceId() {
            if (CommonUtils.isBlank(mCachedDeviceId)) {
                mCachedDeviceId = getDeviceIdInternal();
            }
            return mCachedDeviceId;
    }

    private String getDeviceIdInternal() {
        if (mFingerprintManagerAdapter != null) {
            String deviceId = mFingerprintManagerAdapter.getDeviceID();
            return deviceId;
        }
        return null;
    }

    /**
     * @see com.ifaa.sdk.auth.IAuthenticator#cancel()
     */
    @Override
    public void cancel() {
        if (mFingerprintManagerAdapter != null) {
            try {
                mFingerprintManagerAdapter.cancel();
            } catch (Exception e) {
                // DO NOTHING
            }
        }
    }

    @Override
    public void cancel(Context context) {
        if (mFingerprintManagerAdapter != null) {
            try {
                mFingerprintManagerAdapter.cancel();
            } catch (Exception e) {
                // DO NOTHING
            }
        }
    }

    /**
     * @see com.ifaa.sdk.auth.IAuthenticator#release()
     */
    @Override
    public void release() {
        // do nothing
    }

    /**
     * 构造设备相关信息
     * 
     * @see com.ifaa.sdk.auth.IAuthenticator#getAuthInfo()
     */
    @Override
    public AuthInfo getAuthInfo() {
        return new AuthInfo(Constants.TYPE_FINGERPRINT, 100, 2, 20, Build.MODEL, mFingerprintManagerAdapter != null ? mFingerprintManagerAdapter.getDeviceModel() : "");
    }


    /**
     * 用户注册指纹或者是没有注册指纹或者是注册之后被删除了。
     * 
     * @param token
     * @return
     */
    public synchronized int checkUserStatus(String token) {
        AuthenticatorLOG.fpInfo("ifaa checkUserStatus enter [token:" + token + "]");
        long startTime = System.currentTimeMillis();
        int status = checkUserStatusInternal(token);
        long tmCost = (System.currentTimeMillis() - startTime);
        AuthenticatorLOG.fpInfo("ifaa checkUserStatus exit [status:" + status
                + "] [timecost:" + (tmCost) + "]");
        return status;
    }

    private int checkUserStatusInternal(String token) {
        if (CommonUtils.isBlank(token) == false) {
            if (mFingerprintManagerAdapter != null) {
                int userStatus = mFingerprintManagerAdapter.getUserStatus(token);
                return userStatus;
            }
        }
        AuthenticatorLOG.fpInfo("ifaa checkUserStatus token null");
        return 2;
    }


    @Override
    public boolean hasEnrolled() {
        if (mFingerprintManagerAdapter != null) {
            return mFingerprintManagerAdapter.hasEnrolledFingerprints();
        }
        return false;
    }

    @Override
    public void startSystemEnrollManger() {
        mFingerprintManagerAdapter.startFingerprintManager();
    }


    /**
     * prapareKeyPair 
     * 
     * @param
     * @return
     */
    public void prapareKeyPair() {

    }

    @Override
    @Deprecated
    protected void doRegister(AuthenticatorMessage registerRequest,
                              AuthenticatorCallback authenticatorCallback) {
    }

    @Override
    @Deprecated
    protected void doAuthenticate(AuthenticatorMessage authenticateRequest,
                                  AuthenticatorCallback authenticatorCallback) {
    }

    @Override
    @Deprecated
    protected void doDeregister(AuthenticatorMessage deRegisterRequest,
                                AuthenticatorCallback authenticatorCallback) {
    }

}
